package com.atguigu.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.atguigu.client.OrderFeignClient;
import com.atguigu.config.AlipayConfig;
import com.atguigu.constant.MqConst;
import com.atguigu.entity.OrderInfo;
import com.atguigu.entity.PaymentInfo;
import com.atguigu.enums.PaymentStatus;
import com.atguigu.enums.PaymentType;
import com.atguigu.mapper.PaymentInfoMapper;
import com.atguigu.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.xml.ws.Response;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 支付信息表 服务实现类
 * </p>
 *
 * @author zhangqiang
 * @since 2021-09-07
 */
@Service
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public boolean closeAlipayTrade(Long orderId) throws AlipayApiException {
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderInfo.getOutTradeNo());
        request.setBizContent(bizContent.toString());
        AlipayTradeCloseResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean queryAlipayTrade(Long orderId) throws AlipayApiException {
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("out_trade_no", orderInfo.getOutTradeNo());
        request.setBizContent(jsonObject.toString());
        AlipayTradeQueryResponse execute = alipayClient.execute(request);
        if (execute.isSuccess()){
         return true;
        }
        return false;
    }

    @Override
    public boolean refund(Long orderId) throws AlipayApiException {
        //根据接口退款
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        //设置请求需要的参数
        Map<String, Object> map = new HashMap<>();
        //商家订单号
        map.put("out_trade_no",orderInfo.getOutTradeNo());
        map.put("refund_amount",orderInfo.getTotalMoney());
        //商品说明信息
        map.put("refund_reason","爆了 炸尸了");
        //TODO 向支付宝发起请求退款
        request.setBizContent(JSON.toJSONString(map));
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()){
               //如果退款成功修改支付订单状态为已关闭
            PaymentInfo paymentInfo = getPaymentInfo(orderInfo.getOutTradeNo());
            paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
            baseMapper.updateById(paymentInfo);
            return true;
        }else {
            return false;
        }
    }

    @Override
    public void updatePaymentInfo(Map<String, String> aliParamMap) {
        String outTradeNo = aliParamMap.get("out_trade_no");
        PaymentInfo paymentInfo = getPaymentInfo(outTradeNo);
        //修改订单信息
        paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(aliParamMap.toString());
        //获取支付宝那边生成的订单号
        String tradeNo = aliParamMap.get("trade_no");
        paymentInfo.setTradeNo(tradeNo);
        baseMapper.updateById(paymentInfo);
        //发一条消息修改订单状态,mq
        rabbitTemplate.convertAndSend(MqConst.PAY_ORDER_EXCHANGE,MqConst.PAY_ORDER_ROUTE_KEY,paymentInfo.getOrderId());
        System.out.println("修改订单中:"+tradeNo);
    }

    @Override
    public PaymentInfo getPaymentInfo(String outTradeNo){
        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("out_trade_no", outTradeNo);
        queryWrapper.eq("payment_type", PaymentType.ALIPAY.name());
       return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public String createQrCode(Long orderId) throws AlipayApiException {
        //根据订单id查询订单信息
        OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
        //保存支付信息
        savepaymentInfo(orderInfo);
        //调用支付宝返回二维码支付的接口
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //设置同步回调地址
        request.setReturnUrl(AlipayConfig.return_payment_url);
        //设置一步回调地址
        request.setNotifyUrl(AlipayConfig.notify_payment_url);
        Map<String, Object> map = new HashMap<>();
        map.put("out_trade_no",orderInfo.getOutTradeNo());
        map.put("product_code","FAST_INSTANT_TRADE_PAY");
        map.put("total_amount",orderInfo.getTotalMoney());
        map.put("subject","太热了，买个空调凉快凉快！");
        request.setBizContent(JSON.toJSONString(map));
        return alipayClient.pageExecute(request).getBody();
    }

    private void savepaymentInfo(OrderInfo orderInfo) {
        //判断数据库是否有该支付订单
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderInfo.getId());
        wrapper.eq("payment_type", PaymentType.ALIPAY.name());
        Integer integer = baseMapper.selectCount(wrapper);
        if (integer>0){
            return;
        }
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId()+"");
        paymentInfo.setPaymentType(PaymentType.ALIPAY.name());
        paymentInfo.setPaymentMoney(orderInfo.getTotalMoney());
        paymentInfo.setPaymentContent(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        paymentInfo.setCreateTime(new Date());
        baseMapper.insert(paymentInfo);
    }
}
